package com.njlime.sys.service;

import com.njlime.core.exception.BusinessException;
import com.njlime.core.helper.GlobalValue;
import com.njlime.core.helper.PageBean;
import com.njlime.sys.entities.Menu;
import com.njlime.sys.repository.MenuDao;
import com.njlime.sys.security.util.CacheUtils;
import com.njlime.sys.security.util.UserUtils;
import com.njlime.sys.util.LogUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Created by Dean on 2017-7-19.
 */
@Service
@Transactional(readOnly = true)
public class MenuService {

    @Resource
    private MenuDao menuDao;
    @Resource
    private RoleService roleService;

    /**
     * 获取菜单列表分页
     *
     * @param pageBean
     * @param menu
     * @return
     */
    public PageBean list(PageBean pageBean, Menu menu) {
        return menuDao.list(pageBean, menu);
    }

    /**
     * 根据id获取菜单信息
     *
     * @param id
     * @return
     */
    public Menu get(Integer id) {
        return menuDao.findOne(id);
    }

    /**
     * 根据id获取菜单信息
     *
     * @param id
     * @return
     */
    public Map<String,Object> getById(Integer id) {
        return menuDao.getById(id);
    }

    /**
     * 添加菜单
     *
     * @param menu
     */
    @Transactional(readOnly = false)
    public void addMenu(Menu menu) {
        Menu ori = menuDao.getByUrl(menu.getUrl());
        if(ori != null){
            throw new BusinessException("权限url已存在");
        }
        if (menu.getParent_id() == 0) {
            menu.setParent_ids(menu.getParent_id() + ",");
        } else {
            Menu parent = menuDao.findOne(menu.getParent_id());
            if (parent == null) {
                throw new BusinessException("上级菜单不正确");
            }
            menu.setParent_ids(parent.getParent_ids() + menu.getParent_id() + ",");
        }
        int max_sort = menuDao.getMaxSort();
        menu.setSort(max_sort + 1);
        menu.setCreator(UserUtils.getUser().getId());
        menu.setCreate_time(new Date());
        menu.setIs_del(GlobalValue.NO);
        menu.setStatus(GlobalValue.AVAILABLE);
        menu = menuDao.save(menu);
        //为管理员角色添加该菜单权限
        roleService.insertRoleMenu(GlobalValue.SYS_MANAGE_ROLE, menu.getId());
        CacheUtils.removeAll(UserUtils.USER_CACHE);
        CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
    }

    /**
     * 编辑菜单
     *
     * @param menu
     */
    @Transactional(readOnly = false)
    public void editMenu(Menu menu) {
        Menu ori = menuDao.getByUrl(menu.getUrl());
        if(ori != null && !ori.getId().equals(menu.getId())){
            throw new BusinessException("权限url已存在");
        }
        if (menu.getParent_id() != null) {
            if (menu.getParent_id() == 0) {
                menu.setParent_ids(menu.getParent_id() + ",");
            } else {
                Menu parent = menuDao.findOne(menu.getParent_id());
                if (parent == null) {
                    throw new BusinessException("上级菜单不正确");
                }
                menu.setParent_ids(parent.getParent_ids() + menu.getParent_id() + ",");
            }
        }
        menu.setUpdate_time(new Date());
        menu.setUpdater(UserUtils.getUser().getId());
        menuDao.updateMenu(menu);
        CacheUtils.removeAll(UserUtils.USER_CACHE);
        CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
    }

    /**
     * 批量删除
     *
     * @param idArray
     */
    @Transactional(readOnly = false)
    public void deleteMenu(String[] idArray) {
        if (idArray != null && idArray.length > 0) {
            for (String idStr : idArray) {
                Integer id = Integer.parseInt(idStr);
                int num = menuDao.countByParentId(id);
                if (num > 0) {
                    throw new BusinessException("存在下级菜单，不能删除");
                }
                menuDao.deleteMenu(id);
            }
        }
        CacheUtils.removeAll(UserUtils.USER_CACHE);
        CacheUtils.remove(LogUtils.CACHE_MENU_NAME_PATH_MAP);
    }

    /**
     * 获取菜单树
     *
     * @return
     */
    public List<Map<String, Object>> menuTree(Integer role_id) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        String menu_ids = "";
        if(role_id != null){
            menu_ids = getMenuIdsByRole(role_id);
        }
        List<Menu> menuList = UserUtils.getMenuList();
        if (menuList != null && menuList.size() > 0) {
            for (Menu menu : menuList) {
                if (menu.getStatus() == GlobalValue.UNAVAILABLE) {
                    continue;
                }
                Map<String, Object> map = new HashMap<>();
                map.put("id", menu.getId());
                map.put("parent_id", menu.getParent_id());
                map.put("name", menu.getName());
                if(role_id != null){
                    if(menu_ids.indexOf(menu.getId() + ",") == 0 || menu_ids.indexOf("," + menu.getId() + ",") > 0){
                        map.put("checked", true);
                    }else {
                        map.put("checked", false);
                    }
                }
                mapList.add(map);
            }
            mapList = treeBean(mapList, GlobalValue.TOP_MENU_ID, GlobalValue.PUBLIC_MENU_ID);
        }
        return mapList;
    }

    /**
     * 获取树形菜单
     *
     * @return
     */
    public List<Map<String, Object>> getUserMenu(Integer show_all) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Menu> menuList = UserUtils.getMenuList();
        if (menuList != null && menuList.size() > 0) {
            for (Menu menu : menuList) {
                if (GlobalValue.NO.equals(show_all) && (GlobalValue.UNAVAILABLE.equals(menu.getStatus()) || GlobalValue.NO.equals(menu.getIs_show()))) {
                    continue;
                } else {
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", menu.getId());
                    map.put("parent_id", menu.getParent_id());
                    map.put("name", menu.getName());
                    map.put("sort", menu.getSort());
                    map.put("template", menu.getTemplate());
                    map.put("icon", menu.getIcon());
                    map.put("icon_hover", menu.getIcon_hover());
                    map.put("open","0");
                    map.put("permission", menu.getPermission());
                    map.put("url", menu.getUrl());
                    map.put("is_show", menu.getIs_show());
                    map.put("status", menu.getStatus());
                    resultList.add(map);
                }
            }
            resultList = treeBean(resultList, GlobalValue.TOP_MENU_ID, GlobalValue.TOP_MENU_ID);
        }
        return resultList;
    }
    /**
     * 获取树形菜单
     *
     * @return
     */
    public List<Map<String, Object>> getUserMenu2(Integer show_all,String url ) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Menu> menuList = UserUtils.getMenuList();
        Integer[] idArr = new Integer[2];

        if (menuList != null && menuList.size() > 0) {
            for (Menu menu : menuList) {
                if(url.equals(menu.getUrl())){
                    String[] pids = (menu.getParent_ids() + menu.getId()).split(",");
                    if(pids.length >= 3) {
                        idArr[0] = Integer.valueOf(pids[1]);
                        idArr[1] = Integer.valueOf(pids[2]);
                    }
                    break;
                }
            }

            for (Menu menu : menuList) {
                if (GlobalValue.NO.equals(show_all) && (GlobalValue.UNAVAILABLE.equals(menu.getStatus()) || GlobalValue.NO.equals(menu.getIs_show()))) {
                    continue;
                } else {
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", menu.getId());
                    map.put("parent_id", menu.getParent_id());
                    map.put("name", menu.getName());
                    map.put("sort", menu.getSort());
                    map.put("template", menu.getTemplate());
                    map.put("icon", menu.getIcon());
                    map.put("icon_hover", menu.getIcon_hover());
                    map.put("open","0");
                    map.put("permission", menu.getPermission());
                    map.put("url", menu.getUrl());
                    if(menu.getId().equals(idArr[0]) || menu.getId().equals(idArr[1])){
                        map.put("open","1");
                    }
                    map.put("is_show", menu.getIs_show());
                    map.put("status", menu.getStatus());
                    resultList.add(map);
                }
            }
            resultList = treeBean(resultList, GlobalValue.TOP_MENU_ID, GlobalValue.TOP_MENU_ID);
        }
        return resultList;
    }
    /**
     * 根据角色id获取菜单列表
     *
     * @param role_id
     * @return
     */
    public List<Map<String, Object>> getMenuByRole(Integer role_id) {
        return menuDao.getMenuByRole(role_id);
    }

    /**
     * 获取角色菜单id字符串，逗号隔开
     *
     * @param role_id
     * @return
     */
    public String getMenuIdsByRole(Integer role_id) {
        String menu_ids = "";
        List<Map<String, Object>> list = getMenuByRole(role_id);
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                menu_ids += list.get(i).get("id").toString() + ",";
            }
        }
        return menu_ids;
    }


    /**
     * 递归获取树形结构
     *
     * @param list
     * @param parent_id
     * @return
     */
    private List<Map<String, Object>> treeBean(List<Map<String, Object>> list, int parent_id, int exclude_id) {
        List<Map<String, Object>> nodeList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            Integer pid = Integer.parseInt(map.get("parent_id").toString());
            Integer id = Integer.parseInt(map.get("id").toString());
            if (parent_id == pid && id != exclude_id) {
                List<Map<String, Object>> c_node = treeBean(list, id, exclude_id);
                if (c_node != null && c_node.size() > 0) {
                    map.put("children", c_node);
                }
                nodeList.add(map);
            }
        }
        return nodeList;
    }

    /**
     * 上移下移
     *
     * @param id
     * @param type 1上移 2下移
     */
    @Transactional(readOnly = false)
    public void changeSort(Integer id, Integer type) {
        Menu menu = menuDao.findOne(id);
        Menu next_menu = null;
        if (GlobalValue.UP_SORT == type) {
            next_menu = menuDao.getBeforeSortMenu(id);
        } else {
            next_menu = menuDao.getNextSortMenu(id);
        }
        if (next_menu == null) {
            throw new BusinessException("不允许进行上移或下移");
        }
        int cur_sort = menu.getSort();
        int next_sort = next_menu.getSort();
        menu.setSort(next_sort);
        menu.setUpdate_time(new Date());
        menu.setUpdater(UserUtils.getUser().getId());
        menuDao.updateMenu(menu);
        next_menu.setSort(cur_sort);
        next_menu.setUpdate_time(new Date());
        next_menu.setUpdater(UserUtils.getUser().getId());
        menuDao.updateMenu(next_menu);
        CacheUtils.removeAll(UserUtils.USER_CACHE);
    }

    /**
     * 获取当前用户拥有的页面权限
     * @param pageModel
     * @return
     */
    public String curPagePermission(String pageModel) {
        Menu page = menuDao.getByTemplate(pageModel);
        if(page == null){
            return "";
        }
        String permissions = "";
        List<Menu> menuList = UserUtils.getMenuList();
        for (Menu menu : menuList) {
            if(menu.getParent_ids().startsWith(page.getParent_ids() + page.getId()) && permissions.indexOf(menu.getPermission()) < 0){
                permissions += menu.getPermission() + ",";
            }
        }
        return permissions.substring(0,permissions.length()-1);
    }


}
